# -*- coding: utf-8 -*-
# HTTP
from django.utils import simplejson
from django.shortcuts import render_to_response
from argus.forms import *
from django.template import RequestContext
from django.core.context_processors import csrf
# MYSQL
#from django.db.models import Q
from django.db import connection
from argus.hijacking.models import *
from django.db.models import Count
# UTIL
import time, string
from decimal import Decimal


# Geo
import GeoIP, csv
geo = GeoIP.new(GeoIP.GEOIP_MEMORY_CACHE)
gcity = GeoIP.open("/usr/local/share/GeoIP/GeoLiteCity.dat", GeoIP.GEOIP_MEMORY_CACHE)
gcityv6 = GeoIP.open("/usr/local/share/GeoIP/GeoLiteCityv6.dat", GeoIP.GEOIP_MEMORY_CACHE)
gloc = GeoIP.open("/usr/local/share/GeoIP/GeoIP.dat", GeoIP.GEOIP_MEMORY_CACHE)
asn2GeoIP = {}
eye2AS = {}

def clean_city_name(name):
  name_cl = []
  for c in name:
    if ord(c) < 128 and ord(c) > 0:
      name_cl.append(c)
    else:
      name_cl.append(' ')
  return ''.join(name_cl)

def tmp_constructCityTable():
  if int(time.time()) > 1366909000:
    return
  for v in Visitor.objects.all():
    # loc
    if not (v.latitude and v.longitude):
      continue
    loc = gcity.record_by_addr(v.ip)
    if not loc:
      continue
    v.latitude = int(loc['latitude'] * 10000)
    v.longitude = int(loc['longitude'] * 10000)
    v.save()
    v.agent = v.agent.lower()
    # city
    if 'bot' in v.agent or 'spider' in v.agent or 'python' in v.agent:
      continue
    city = City.objects.filter(
      latitude = v.latitude, longitude = v.longitude)
    if not city:
      City.objects.create(
        latitude = v.latitude, longitude = v.longitude,
        name = clean_city_name(
            loc['region_name'] if loc['region_name'] else ('(%s)' % loc['country_name'])
        ), pageview = 1
      )
    else:
      city[0].pageview += 1
      city[0].save()

def visitorStat(request, count=False):
  ip = request.META.get('REMOTE_ADDR', '')
  if ip == '166.111.68.233' or ip.startswith('59.66.215.'): # lab & dorm
    #import threading
    #constructCityTableThread = threading.Thread(target = tmp_constructCityTable)
    #constructCityTableThread.daemon = True
    #constructCityTableThread.start()
    # count
    if count:
      return Visitor.objects.exclude(
        agent__icontains='bot').exclude(
        agent__icontains='spider').exclude(
        agent__icontains='python').count()# + 12662 # 12662 page view, 2439 home view.
    else:
      return
  agent = request.META.get('HTTP_USER_AGENT', '')
  path = request.path
  refer = request.META.get('HTTP_REFERER','')
  # loc
  loc = gcity.record_by_addr(ip)
  if loc:
    latitude = int(loc['latitude'] * 10000)
    longitude = int(loc['longitude'] * 10000)
    Visitor.objects.create(
      ip = ip[:64], agent = agent[:256], path = path[:32], refer = refer[:64],
      latitude = latitude, longitude = longitude
    )
    # city
    lagent = agent.lower()
    if not ('bot' in lagent or 'spider' in lagent or 'python' in lagent):
      city = City.objects.filter(
        latitude = latitude, longitude = longitude
      )
      if not city:
        City.objects.create(
          latitude = latitude, longitude = longitude,
          name = clean_city_name(
              loc['region_name'] if loc['region_name'] else ('(%s)' % loc['country_name'])
          ), pageview = 1
        )
      else:
        city[0].pageview += 1
        city[0].save()
  else:
    Visitor.objects.create(
      ip = ip[:64], agent = agent[:256], path = path[:32], refer = refer[:64],
    )
  if count:
    return Visitor.objects.exclude(
      agent__icontains='bot').exclude(
      agent__icontains='spider').exclude(
      agent__icontains='python').count()# + 12662 # 12662 page view, 2439 home view.
  else:
    return

def getPrefixRange(prefix_dec):
  ib = prefix_dec.rindex(' ')
  if ib == 8:
    return (prefix_dec[:4], prefix_dec[4:8], int(prefix_dec[9:]))
  else:
    return (prefix_dec[:16], prefix_dec[16:32], int(prefix_dec[33:]))

def getFingerprints(aid):
  other_prefix = []
  signatures = []
  alarms = Alarm.objects.filter(alarm_id = ('%s' % aid))
  if alarms:
    alarm_at_same_time = Alarm.objects.filter(
      time = alarms[0].time, homeas = alarms[0].homeas,
      bad_path = alarms[0].bad_path).order_by('alarm_id')
    for i in xrange(0, len(alarm_at_same_time)):
      pfx_dec = alarm_at_same_time[i].prefix_dec
      prefix_cc = geo.country_code_by_addr(pfx_dec[:pfx_dec.index('/')])
      if not prefix_cc:
        prefix_cc = ""
      prefix_cn = geo.country_name_by_addr(pfx_dec[:pfx_dec.index('/')])
      if not prefix_cn:
        prefix_cn = ""
      if not signatures:
        signatures = Signature.objects.filter(
            alarm_id = ('%s' % alarm_at_same_time[i].alarm_id))
        if signatures:
          alarms = []
          alarms.append(alarm_at_same_time[i])
          aid = alarms[0].alarm_id
          continue
      other_prefix.append((
        alarm_at_same_time[i].prefix_dec,
        alarm_at_same_time[i].oldhomeas,
        prefix_cc, prefix_cn, ))
  sum = sum6 = 0.0
  cnt = cnt6 = 0
  firstP = first6 = firstR = -1
  maxf = -1.0
  minf = 1.0
  sigs = [None] * 120
  cnt0x = [None] * 120
  cntx0 = [None] * 120
  cntxx = [None] * 120
  for i in xrange(len(signatures)):
    sg = signatures[i]
    if sg.elapse_time >= 0 and sg.elapse_time <= 120:
      sigs[sg.elapse_time] = sg.sig
      cnt0x[sg.elapse_time] = sg.cnt00 + sg.cnt01
      cntx0[sg.elapse_time] = sg.cnt00 + sg.cnt10
      cntxx[sg.elapse_time] = sg.cnt00 + sg.cnt01 + sg.cnt10 + sg.cnt11
      if maxf < sg.sig:
        maxf = sg.sig
      if minf > sg.sig:
        minf = sg.sig
      if firstP == -1:
        firstP = sg.elapse_time
      if firstR == -1 and cnt0x[sg.elapse_time]:
        firstR = sg.elapse_time
      if first6 == -1 and sg.sig >= 0.6:
        first6 = sg.elapse_time
      if i < len(signatures) - 1:
        endT = signatures[i + 1].elapse_time
      else:
        endT = 120
      sum += (endT - sg.elapse_time) * sg.sig
      cnt += endT - sg.elapse_time
      if sg.sig >= 0.6:
        sum6 += (endT - sg.elapse_time) * sg.sig
        cnt6 += endT - sg.elapse_time
  alarms_detail = []
  if alarms:
    as0 = as1 = as2 = 0
    if alarms[0].bad_path:
      ASes = string.split(alarms[0].bad_path, ' ')
      as2 = ASes[-1]
      as1 = ASes[-2]
      if len(ASes) == 3: as0 = int(ASes[0])
    prefix_cc = geo.country_code_by_addr(
      alarms[0].prefix_dec[:alarms[0].prefix_dec.index('/')])
    if not prefix_cc:
      prefix_cc = ""
    if first6 != -1:
      alarms_detail.append((alarms[0],
                  time.strftime("%y-%m-%d %T", time.gmtime(alarms[0].time)),
                  first6 - firstR, # first alarm
                  cnt6, # alarm last
                  ("%.2lf" % (sum6 / cnt6)), # probability
                  as0, as1, as2, other_prefix, prefix_cc,
                ))
    elif firstP != -1:
      alarms_detail.append((alarms[0],
                  time.strftime("%y-%m-%d %T", time.gmtime(alarms[0].time)),
                  ("%.2lf" % maxf),
                  ("%.2lf" % minf),
                  ("%.2lf" % (sum / cnt)),
                  as0, as1, as2, other_prefix, prefix_cc,
                ))
  base = 120
  if signatures:
    base = signatures[0].elapse_time
  del sigs[:base]
  del cnt0x[:base]
  del cntx0[:base]
  del cntxx[:base]
  for i in xrange(1, len(sigs)):
    if sigs[i] == None:
      sigs[i] = sigs[i - 1]
      cnt0x[i] = cnt0x[i - 1]
      cntx0[i] = cntx0[i - 1]
      cntxx[i] = cntxx[i - 1]
  if cnt6 < 10:
    first6 = -1
  updates = Bgpmon.objects.filter(alarm_id = ('%s' % aid))
  upts = []
  for u in updates:
    full_path = u.path.split(' ')
    zip_path = []
    aspp = []
    for a in full_path:
      if zip_path and a == zip_path[-1]:
        aspp[-1] += 1
      else:
        zip_path.append(a)
        aspp.append(1)
    bad_flag = False
    for i in xrange(len(aspp)):
      l = len(zip_path[i])
      if aspp[i] != 1:
        zip_path[i] += ('<B>x%d</B>' % aspp[i])
      if alarms[0].homeas:
        if i + 1 == len(aspp) and ('%d' % alarms[0].homeas) == zip_path[i][:l]:
          zip_path[i] = '<FONT COLOR="red">' + zip_path[i] + '</FONT>'
      else:
        if alarms[0].bad_path.startswith(zip_path[i][:l] + ' ') and (
            (i+1 < len(aspp) and alarms[0].bad_path.count(' ') == 1 and
             alarms[0].bad_path.endswith(' ' + zip_path[i+1]))
            or
            (i+2 < len(aspp) and alarms[0].bad_path.count(' ') == 2 and
             alarms[0].bad_path.endswith(' ' + zip_path[i + 1] + ' ' + zip_path[i+2]))
           ):
          zip_path[i] = '<FONT COLOR="red">' + zip_path[i]
          bad_flag = True
        elif bad_flag and alarms[0].bad_path.endswith(' ' + zip_path[i][:l]):
          zip_path[i] += '</FONT>'
          bad_flag = False
    #[zip_path.append(i) for i in full_path if not i in zip_path]
    zip_path = ' '.join(zip_path)
    upts.append((
      u.time - alarms[0].time,
      u.time,
      time.strftime("%y-%m-%d %T", time.gmtime(u.time)),
      u.monip_dec,
      u.path, zip_path))
  return (first6, alarms_detail, sigs, cnt0x, cntx0, cntxx, base, upts)

def initASNum2GeoIP():
  #asn2GeoIP = {}
  with open('/var/www/argus/ASNum2GeoIP.csv', 'rb') as f:
    csvreader = csv.reader(f)
    for line in csvreader:
      if line[2] is None or line[2] == "" or line[2] == " ":
        continue
      if line[1] is None or line[1] == "" or line[1] == " ":
        continue
      asn2GeoIP[line[0]]={'lat':line[2],'longi':line[1],'title':line[0]}

def initEye2AS():
  if not asn2GeoIP:
    initASNum2GeoIP()
  cursor = connection.cursor()
  cursor.execute("SELECT eye_id, asn FROM eye")
  eyelist = cursor.fetchall()
  for eye in eyelist :
    eye2AS[eye[0]] = eye[1]


def getASPaths(aid):
  upts = {}
  alarms = Alarm.objects.filter(alarm_id = ('%s' % aid))
  if not alarms:
    return {}
  upts["time"]=alarms[0].time

  updates = Bgpmon.objects.filter(alarm_id = ('%s' % aid))
  if not updates:
    return {}
  paths = []
  tmppaths = []
  badpaths = []
  goodpaths = []
  badpathsegment = []
  if alarms[0].homeas:
    badpathsegment.append('%d' % alarms[0].homeas)
  else:
    badpathsegment = alarms[0].bad_path.split() 
  for u in updates:
    if u.path is None or u.path == "":
      continue
    full_path = u.path.split()
    paths.append(full_path)
    zip_path = []
    bad_flag = False
    pre = None
    for a in full_path:
      if not a or a == "":
        continue
      if not pre :
        zip_path.append(a)
      elif a != pre:
        zip_path.append(a)
      pre = a
    tmppath = ' '.join([str(i) for i in zip_path])
    if alarms[0].homeas:
      if zip_path[-1] == ('%d' % alarms[0].homeas):
        bad_flag = True
    else:
      if tmppath.find(alarms[0].bad_path) != -1:
        bad_flag = True
    tmppaths.append(tmppath)
    if bad_flag:
      badpaths.append(zip_path)
    else:
      goodpaths.append(zip_path)    
    #[zip_path.append(i) for i in full_path if not i in zip_path]
    #zip_path = ' '.join(zip_path)
  pfxpoint = {}
  pfx_dec = alarms[0].prefix_dec
  pfxpoint["prefix_dec"] = pfx_dec
  pfxpoint["aid"] = alarms[0].alarm_id
  pfxpoint["prefix_AS"] = alarms[0].oldhomeas
  loc = None
  if alarms[0].is_ipv6:
    loc = gcityv6.record_by_addr_v6(pfx_dec[:pfx_dec.index('/')])
  else:
    loc = gcity.record_by_addr(pfx_dec[:pfx_dec.index('/')])
  if loc :
    pfxpoint['lat'] = loc['latitude']
    pfxpoint['longi'] = loc['longitude']
  upts["paths"] = paths
  upts["tmppaths"] = tmppaths
  upts["badpaths"] = badpaths
  upts["goodpaths"] = goodpaths
  upts["pfxpoint"] = pfxpoint
  #upts["badpath"] = badpath
  #upts["badpathstr"] = alarms[0].bad_path
  upts["badpathsegment"] = badpathsegment

  #eye status
  if not eye2AS:
    initEye2AS()
  cursor = connection.cursor()
  cursor.execute("SELECT srv_id, isoldhome FROM route WHERE alarm_id = %s", [aid])
  eyelist = cursor.fetchall()
  eyes = {}
  for eye in eyelist :
    if eye[1] == 0 :
      eyes[eye[0]] = 0
    else :
      if not eyes.has_key(eye[0]) :
        eyes[eye[0]] = 1
  pollutedList = []
  unpollutedList = []
  for eye in eyes :
    e={}
    e["eye_id"] = eye
    asn=eye2AS.get(eye,None)
    if asn :
      e["asn"] = asn
      loc=asn2GeoIP.get(str(asn))
      if loc:
        e["lat"] = loc["lat"]
        e["longi"] = loc["longi"]
        e["title"] = loc["title"]
    if eyes[eye] == 0:
      pollutedList.append(e)
    else :
      unpollutedList.append(e)
  upts["pollutedList"] = pollutedList
  upts["unpollutedList"] = unpollutedList

  return upts

def fingerprints(request, aid):
  template_var={} 
  visitorStat(request)
  (first6, alarms_detail, sigs, cnt0x, cntx0, cntxx, base, upts
      ) = getFingerprints(aid)
  #raise upts
  result = getASPaths(aid)
  if not asn2GeoIP:
    initASNum2GeoIP()
  goods = set()
  bads = set()
  goodpoints = []
  badpoints = []
  badpaths = []
  if result and result["badpaths"]:
    for path in result["badpaths"]:
      points = []
      for point in path:
        tmpvar = asn2GeoIP.get(str(point))
        if tmpvar:
          points.append(tmpvar)
          goods.add(point)
      badpaths.append(points)
  goodpaths = []
  if result and result["goodpaths"]:
    for path in result["goodpaths"]:
      points = []
      for point in path:
        tmpvar = asn2GeoIP.get(str(point))
        if tmpvar:
          points.append(tmpvar)
          #goods.add(point)
      goodpaths.append(points)
  badpathsegment = []
  if result and result["badpathsegment"]:
    for point in result["badpathsegment"]:
      tmpvar = asn2GeoIP.get(str(point))
      if tmpvar:
        badpathsegment.append(tmpvar)
        bads.add(point)
        if point in goods:
          goods.remove(point)
  for p in goods:
    goodpoints.append(asn2GeoIP[str(p)])
  for p in bads:
    badpoints.append(asn2GeoIP[str(p)])
  

  template_var["pollutedList"]=result["pollutedList"]
  template_var["unpollutedList"]=result["unpollutedList"]

  template_var["badpaths"] = badpaths
  template_var["goodpaths"] = goodpaths
  template_var["badpathsegment"] = badpathsegment
  template_var["pfxpoint"] = result["pfxpoint"]
  template_var["goodpoints"] = goodpoints
  template_var["badpoints"] = badpoints
  template_var['first6'] = first6
  template_var['alarms'] = alarms_detail
  template_var['sigs'] = sigs
  template_var['cnt0x'] = cnt0x
  template_var['cntx0'] = cntx0
  template_var['cntxx'] = cntxx
  template_var['base'] = base 
  template_var['upts'] = upts 
  template_var['aid'] = aid
  #raise template_var
  #Defence Advice
  Advices = []
  if first6 != -1:
    #attacker AS
    if alarms_detail[0][0].homeas: #origin AS anomaly
      suggestion = "undo network " + alarms_detail[0][0].prefix_dec
      note = "withdraw the prefix announcement"
      Advices.append({"asType":"Attacker AS","suggestion":suggestion,"note":note})
    else: #AS path anomaly
      (ip,length) = alarms_detail[0][0].prefix_dec.split('/')
      suggestion = "distribute-list hijacking-filter out<br/>"
      suggestion += "access-list hijacking-filter deny " + ip + " 0.0.0.255<br/>"
      suggestion += "access-list hijacking-filter permit 0.0.0.0 255.255.255.255"
      note = "filter out all routing updates about the prefix"
      Advices.append({"asType":"Attacker AS","suggestion":suggestion,"note":note})
    #victim AS
    (ip,length) = alarms_detail[0][0].prefix_dec.split('/')
    if int(length) < 31:
      suggestion = "network " + ip + "/" + str(int(length)+1)
      note = "announce a more specific prefix"
      Advices.append({"asType":"Victim AS","suggestion":suggestion,"note":note})
    #other AS
    if alarms_detail[0][0].homeas: #origin AS anomaly
      suggestion = "filter-list hijacking-filter in<br/>"
      suggestion += "ip as-path access-list hijacking-filter deny _" + str(alarms_detail[0][0].homeas) + "$<br/>"
      suggestion += "ip as-path access-list hijacking-filter permit .*" 
      note = "filter all routing updates about the attcker AS"
      Advices.append({"asType":"Other AS","suggestion":suggestion,"note":note})
    else:
      result = alarms_detail[0][0].bad_path.split(' ')
      tmpstr = '_'.join(result)
      suggestion = "filter-list hijacking-filter in<br/>"
      suggestion += "ip as-path access-list hijacking-filter deny _" + tmpstr + "_<br/>"
      suggestion += "ip as-path access-list hijacking-filter permit .*" 
      note = "filter all routing updates about the anomalous AS path"
      Advices.append({"asType":"Other AS","suggestion":suggestion,"note":note})
  template_var['Advices'] = Advices
  return render_to_response('fingerprints.html', template_var,context_instance=RequestContext(request))

def aspath(request, aid):
  template_var={} 
  result = getASPaths(aid)
  template_var["time"]=time.strftime("%y-%m-%d %T", time.gmtime(result["time"]))
  if not asn2GeoIP:
    initASNum2GeoIP()
  goods = set()
  bads = set()
  goodpoints = []
  badpoints = []
  badpaths = []
  if result and result["badpaths"]:
    for path in result["badpaths"]:
      points = []
      for point in path:
        tmpvar = asn2GeoIP.get(str(point))
        if tmpvar:
          points.append(tmpvar)
          goods.add(point)
      badpaths.append(points)
  goodpaths = []
  if result and result["goodpaths"]:
    for path in result["goodpaths"]:
      points = []
      for point in path:
        tmpvar = asn2GeoIP.get(str(point))
        if tmpvar:
          points.append(tmpvar)
          #goods.add(point)
      goodpaths.append(points)
  badpathsegment = []
  if result and result["badpathsegment"]:
    for point in result["badpathsegment"]:
      tmpvar = asn2GeoIP.get(str(point))
      if tmpvar:
        tmpvar['asn']=point
        badpathsegment.append(tmpvar)
        bads.add(point)
        if point in goods:
          goods.remove(point)
  for p in goods:
    goodpoints.append(asn2GeoIP[str(p)])
  for p in bads:
    badpoints.append(asn2GeoIP[str(p)])
  points = []
  points.append({'lat':37.772323,'longi':-122.214897})
  points.append({'lat':21.291982,'longi':-157.821856})
  points.append({'lat':-18.142599,'longi':178.431})
  points.append({'lat':-27.46758,'longi':153.027892})

  template_var["pollutedList"]=result["pollutedList"]
  template_var["unpollutedList"]=result["unpollutedList"]

  #template_var["paths"] = paths
  template_var["badpaths"] = badpaths
  template_var["goodpaths"] = goodpaths
  template_var["badpathsegment"] = badpathsegment
  template_var["points"] = points
  template_var["tmppaths"] = result["tmppaths"] 
  template_var["pfxpoint"] = result["pfxpoint"]
  template_var["goodpoints"] = goodpoints
  template_var["badpoints"] = badpoints
  
  return render_to_response('aspath.html', template_var)

def aspathbd(request, aid):
  template_var={} 
  result = getASPaths(aid)
  template_var["time"]=time.strftime("%y-%m-%d %T", time.gmtime(result["time"]))
  if not asn2GeoIP:
    initASNum2GeoIP()
  goods = set()
  bads = set()
  goodpoints = []
  badpoints = []
  badpaths = []
  if result and result["badpaths"]:
    for path in result["badpaths"]:
      points = []
      for point in path:
        tmpvar = asn2GeoIP.get(str(point))
        if tmpvar:
          points.append(tmpvar)
          goods.add(point)
      badpaths.append(points)
  goodpaths = []
  if result and result["goodpaths"]:
    for path in result["goodpaths"]:
      points = []
      for point in path:
        tmpvar = asn2GeoIP.get(str(point))
        if tmpvar:
          points.append(tmpvar)
          #goods.add(point)
      goodpaths.append(points)
  badpathsegment = []
  if result and result["badpathsegment"]:
    for point in result["badpathsegment"]:
      tmpvar = asn2GeoIP.get(str(point))
      if tmpvar:
        tmpvar['asn']=point
        badpathsegment.append(tmpvar)
        bads.add(point)
        if point in goods:
          goods.remove(point)
  for p in goods:
    goodpoints.append(asn2GeoIP[str(p)])
  for p in bads:
    badpoints.append(asn2GeoIP[str(p)])
  points = []
  points.append({'lat':37.772323,'longi':-122.214897})
  points.append({'lat':21.291982,'longi':-157.821856})
  points.append({'lat':-18.142599,'longi':178.431})
  points.append({'lat':-27.46758,'longi':153.027892})

  template_var["pollutedList"]=result["pollutedList"]
  template_var["unpollutedList"]=result["unpollutedList"]

  #template_var["paths"] = paths
  template_var["badpaths"] = badpaths
  template_var["goodpaths"] = goodpaths
  template_var["badpathsegment"] = badpathsegment
  template_var["points"] = points
  template_var["tmppaths"] = result["tmppaths"] 
  template_var["pfxpoint"] = result["pfxpoint"]
  template_var["goodpoints"] = goodpoints
  template_var["badpoints"] = badpoints
  
  return render_to_response('aspathbd.html', template_var)

def getHijackingPoints():
  curtime = int(time.time())
  deadline = curtime - 3600 * 24 * 30 * 24 #two years
  result = {}
  points_v4 = []
  points_v6 = []

  cursor = connection.cursor()
  sql_param=[deadline]
  #cursor.execute("SELECT alarm_id, time, is_ipv6, prefix_dec, is_hijacking from alarm where is_hijacking in ('y', '6') and time > %s", sql_param)
  cursor.execute("SELECT alarm_id, time, is_ipv6, prefix_dec, is_hijacking from hijacking_demo where time > %s", sql_param)
  alarms = cursor.fetchall()
  for alarm in alarms:
    if alarm[2] == 1 :
      pfx_dec = alarm[3]
      loc = gcityv6.record_by_addr_v6(pfx_dec[:pfx_dec.index('/')])
      if not loc or not loc['latitude'] or not loc['longitude']:
        continue
      points_v6.append({'lat':loc['latitude'],'longi':loc['longitude'],'pfx':pfx_dec,'aid':alarm[0],'time':alarm[1]})
    elif alarm[4] == 'Y' :
      pfx_dec = alarm[3]
      loc = gcity.record_by_addr(pfx_dec[:pfx_dec.index('/')])
      if not loc or not loc['latitude'] or not loc['longitude']:
        continue
      points_v4.append({'lat':loc['latitude'],'longi':loc['longitude'],'pfx':pfx_dec,'aid':alarm[0],'time':alarm[1]})

  ___devil='''
  alarms_v4 = Alarm.objects.filter(is_hijacking = 'y', is_ipv6 = 0, time__gte = deadline).order_by("-time")
  alarms_v6 = Alarm.objects.filter(is_hijacking__in = ['y','6'], is_ipv6 = 1, time__gte = deadline).order_by("-time")

  if alarms_v4:
    for alarm in alarms_v4:
      pfx_dec = alarm.prefix_dec
      loc = gcity.record_by_addr(pfx_dec[:pfx_dec.index('/')])
      if not loc or not loc['latitude'] or not loc['longitude']:
        continue
      points_v4.append({'lat':loc['latitude'],'longi':loc['longitude'],'pfx':pfx_dec,'aid':alarm.alarm_id,'time':alarm.time})

  if alarms_v6:
    for alarm in alarms_v6:
      pfx_dec = alarm.prefix_dec
      loc = gcityv6.record_by_addr_v6(pfx_dec[:pfx_dec.index('/')])
      if not loc or not loc['latitude'] or not loc['longitude']:
        continue
      points_v6.append({'lat':loc['latitude'],'longi':loc['longitude'],'pfx':pfx_dec,'aid':alarm.alarm_id,'time':alarm.time})
  '''

  result["points_v4"] = points_v4
  result["points_v6"] = points_v6
  result["curtime"] = curtime
  return result
      
def getStatusMap(request):  
  ___devil='''
  template_var = {}
  result = getHijackingPoints()
  if result:
    template_var['points_v4'] = result["points_v4"]
    template_var['points_v6'] = result["points_v6"]
    template_var['curtime'] = result["curtime"]
  result = getVisitors(request)
  if result:
    template_var['citys'] = result['citys']
    template_var['visitors'] = result['visitors']
    template_var['dpvs'] = result['dpvs']
  template_var['monitors'] = getMonitors()
  #raise Exception(template_var)
  return render_to_response('statusmap.html', template_var, context_instance=RequestContext(request))
  '''

  template_var = getVisitors(request)
  
  result = getHijackingPoints()
  if result:
    template_var['points_v4'] = result["points_v4"]
    template_var['points_v6'] = result["points_v6"]
    template_var['curtime'] = result["curtime"]
  template_var['monitors'] = getMonitors()
  return render_to_response('statusmap.html', template_var, context_instance=RequestContext(request))

def getStatusMapbd(request):  
  template_var = getVisitors(request)
  
  result = getHijackingPoints()
  if result:
    template_var['points_v4'] = result["points_v4"]
    template_var['points_v6'] = result["points_v6"]
    template_var['curtime'] = result["curtime"]
  template_var['monitors'] = getMonitors()
  return render_to_response('statusmapbd.html', template_var, context_instance=RequestContext(request))


def getMonitors():
  #eye status
  if not eye2AS:
    initEye2AS()
  monitors = []
  for eye in eye2AS :
    e={}
    e["eye_id"] = eye
    asn=eye2AS.get(eye,None)
    if asn :
      e["asn"] = asn
      loc=asn2GeoIP.get(str(asn))
      if loc:
        e["lat"] = loc["lat"]
        e["longi"] = loc["longi"]
        e["title"] = loc["title"]
        monitors.append(e)
  x={}
  x["eye_id"]=0
  x["asn"]=4538
  x["lat"]=40.007883
  x["longi"]=116.320555
  x["title"]=4538
  monitors.append(x)
  return monitors




def getV4StatusMap(request):  
  return render_to_response('statusmapv4.html')

def getV6StatusMap(request):  
  return render_to_response('statusmapv6.html')

def getDefaultRecentAlarms(topx, prefix="", AS="", rpki=""):
  fig_low, fig_high = (0.6, 1.0)
  cursor = connection.cursor()
  sql_param = []
  prefix_condition = ""
  AS_condition = ""
  rpki_condition = ""
  if prefix:
    (ipbeg, ipend, psize) = getPrefixRange(prefix)
    prefix_condition = " is_ipv6 = %s AND ipbeg >= %s AND ipend <= %s AND "
    sql_param.append(len(ipbeg) == 16)
    sql_param.append(ipbeg)
    sql_param.append(ipend)
  if AS:
    iAS = int(AS)
    AS_condition = """ (homeas = %s OR oldhomeas = %s
        OR bad_path LIKE %s OR bad_path LIKE %s
        OR bad_path LIKE %s) AND """
    sql_param.append(iAS)
    sql_param.append(iAS)
    sql_param.append('%% %s' % AS)
    sql_param.append('%s %%' % AS)
    sql_param.append('%% %s %%' % AS)
  if rpki:
    rpki_condition = " rpki = '%s' AND " % rpki
  sql_param.append(topx)
  cursor.execute(""" SELECT alarm_id FROM alarm WHERE """
    + prefix_condition + AS_condition + rpki_condition +
    """ is_hijacking = 'Y' ORDER BY alarm_id DESC LIMIT %s """, sql_param)
  alarms = cursor.fetchall()
  alarms_info = {}
  alarm_ids = []
  for am in alarms:
    # FirstAlarm, AlarmLast, E(Fing. in [low, high]), OldOrigins, FirstBadRoute
    alarms_info[am[0]] = [-1, 0, 0, 0, -1]
    alarm_ids.append(am[0])
  alarms = Alarm.objects.filter(alarm_id__in = alarm_ids).order_by('-alarm_id')
  signatures = Signature.objects.filter(alarm_id__in = alarm_ids)
  sum = 0.0
  cnt = 0
  for i in xrange(len(signatures)):
    if (i > 0) and (signatures[i].alarm_id != signatures[i - 1].alarm_id): # one alarm over
      if cnt == 0: alarms_info[signatures[i - 1].alarm_id][2] = fig_low
      else: alarms_info[signatures[i - 1].alarm_id][2] = sum / cnt
      alarms_info[signatures[i - 1].alarm_id][1] = cnt
      sum = 0.0
      cnt = 0
    if (signatures[i].sig >= fig_low) and (signatures[i].sig <= fig_high):
      if alarms_info[signatures[i].alarm_id][0] == -1:
        alarms_info[signatures[i].alarm_id][0] = signatures[i].elapse_time
      if (i < len(signatures) - 1) and (signatures[i].alarm_id == signatures[i + 1].alarm_id):
        cnt += signatures[i + 1].elapse_time - signatures[i].elapse_time
        sum += (signatures[i + 1].elapse_time - signatures[i].elapse_time) * signatures[i].sig
      else:
        cnt += 120 - signatures[i].elapse_time
        sum += (120 - signatures[i].elapse_time) * signatures[i].sig
    if alarms_info[signatures[i].alarm_id][4] == -1 and (
        signatures[i].cnt00 + signatures[i].cnt01):
      alarms_info[signatures[i].alarm_id][4] = signatures[i].elapse_time
  if len(signatures) > 0:
    if cnt == 0:
      alarms_info[signatures[len(signatures) - 1].alarm_id][2] = fig_low
    else:
      alarms_info[signatures[len(signatures) - 1].alarm_id][2] = sum / cnt
    alarms_info[signatures[len(signatures) - 1].alarm_id][1] = cnt
  alarms_detail = []
  for i in xrange(len(alarms)):
    prefix_cc = geo.country_code_by_addr(
      alarms[i].prefix_dec[:alarms[i].prefix_dec.index('/')])
    if not prefix_cc:
      prefix_cc = ""
    as0 = as1 = as2 = 0
    if alarms[i].bad_path:
      ASes = string.split(alarms[i].bad_path, ' ')
      as2 = ASes[-1]
      as1 = ASes[-2]
      if len(ASes) == 3: as0 = int(ASes[0])
    num_prefix = Alarm.objects.filter(
        time = alarms[i].time, homeas = alarms[i].homeas,
        bad_path = alarms[i].bad_path).count() - 1
    alarms_detail.append((
      alarms[i],
      time.strftime("%y-%m-%d %T", time.gmtime(alarms[i].time)),
      alarms_info[alarms[i].alarm_id][0] - alarms_info[alarms[i].alarm_id][4], # first alarm
      alarms_info[alarms[i].alarm_id][1],       # alarm last
      ("%.2lf" % alarms_info[alarms[i].alarm_id][2]), # average fingerprint. (probability)
      as0, as1, as2, num_prefix, prefix_cc,
    ))
  return alarms_detail

def getRecentAlarms(fig_low, fig_high, fig_last, topx, prefix, AS, rpki): # get recent topx alarms
  if (fig_low == 0.6) and (fig_high == 1.0) and (fig_last == 10):
    return getDefaultRecentAlarms(topx, prefix, AS, rpki)
  cursor = connection.cursor()
  prefix_condition = ""
  AS_condition = ""
  rpki_condition = ""
  sql_param = []
  if prefix:
    (ipbeg, ipend, psize) = getPrefixRange(prefix)
    prefix_condition = " is_ipv6 = %s AND ipbeg >= %s AND ipend <= %s AND "
    sql_param.append(len(ipbeg) == 16)
    sql_param.append(ipbeg)
    sql_param.append(ipend)
  if AS:
    iAS = int(AS)
    AS_condition = """ (homeas = %s OR oldhomeas = %s
        OR bad_path LIKE %s OR bad_path LIKE %s
        OR bad_path LIKE %s) AND """
    sql_param.append(iAS)
    sql_param.append(iAS)
    sql_param.append('%% %s' % AS)
    sql_param.append('%s %%' % AS)
    sql_param.append('%% %s %%' % AS)
  if rpki:
    rpki_condition = " rpki = '%s' AND " % rpki
  # select
  goon_flag = True
  alarms_detail = []
  end_alarm_id = (1 << 31)
  i_end_alarm_id = len(sql_param)
  sql_param.extend([end_alarm_id, fig_low, fig_high, topx * 2])
  while goon_flag:
    goon_flag = False
    sql_param[i_end_alarm_id] = end_alarm_id
    cursor.execute(""" SELECT alarm_id FROM alarm WHERE """
      + prefix_condition + AS_condition + rpki_condition +
      """ alarm_id < %s AND EXISTS (
        SELECT * FROM signature WHERE
        signature.alarm_id = alarm.alarm_id AND
        sig >= %s AND sig <= %s
      ) ORDER BY alarm_id DESC LIMIT %s
      """, sql_param)
    alarms = cursor.fetchall()
    alarms_info = {}
    alarm_ids = []
    for am in alarms:
      # FirstAlarm, AlarmLast, E(Fing. in [low, high]), OldOrigins, FirstBadRoute
      alarms_info[am[0]] = [-1, 0, 0, 0, -1]
      alarm_ids.append(am[0])
    if alarm_ids: end_alarm_id = alarm_ids[-1]
    signatures = Signature.objects.filter(alarm_id__in = alarm_ids)
    sum = 0.0
    cnt = 0
    for i in xrange(len(signatures)):
      if (i > 0) and (signatures[i].alarm_id != signatures[i - 1].alarm_id): # one alarm over
        if cnt == 0:
          alarms_info[signatures[i - 1].alarm_id][2] = fig_low
        else:
          alarms_info[signatures[i - 1].alarm_id][2] = sum / cnt
        alarms_info[signatures[i - 1].alarm_id][1] = cnt
        sum = 0.0
        cnt = 0
      if (signatures[i].sig >= fig_low) and (signatures[i].sig <= fig_high):
        if alarms_info[signatures[i].alarm_id][0] == -1:
          alarms_info[signatures[i].alarm_id][0] = signatures[i].elapse_time
        if (i < len(signatures) - 1) and (
            signatures[i].alarm_id == signatures[i + 1].alarm_id):
          cnt += signatures[i + 1].elapse_time - signatures[i].elapse_time
          sum += (signatures[i + 1].elapse_time - signatures[i].elapse_time) * signatures[i].sig
        else:
          cnt += 120 - signatures[i].elapse_time
          sum += (120 - signatures[i].elapse_time) * signatures[i].sig
      if alarms_info[signatures[i].alarm_id][4] == -1 and (
          signatures[i].cnt00 + signatures[i].cnt01):
        alarms_info[signatures[i].alarm_id][4] = signatures[i].elapse_time
    if len(signatures) > 0:
      if cnt == 0:
        alarms_info[signatures[len(signatures) - 1].alarm_id][2] = fig_low
      else:
        alarms_info[signatures[len(signatures) - 1].alarm_id][2] = sum / cnt
      alarms_info[signatures[len(signatures) - 1].alarm_id][1] = cnt
    remove_ids = []
    for aid, info in alarms_info.iteritems():
      if info[1] < fig_last:
        remove_ids.append(aid)
    for rid in remove_ids:
      del alarms_info[rid]
    alarms = Alarm.objects.filter(
        alarm_id__in = alarms_info.keys()).order_by('-alarm_id')
    for i in xrange(len(alarms)):
      prefix_cc = geo.country_code_by_addr(
        alarms[i].prefix_dec[:alarms[i].prefix_dec.index('/')])
      if not prefix_cc: prefix_cc = ""
      as0 = as1 = as2 = 0
      if alarms[i].bad_path:
        ASes = string.split(alarms[i].bad_path, ' ')
        as2 = ASes[-1]
        as1 = ASes[-2]
        if len(ASes) == 3: as0 = int(ASes[0])
      num_prefix = Alarm.objects.filter(
          time = alarms[i].time, homeas = alarms[i].homeas,
          bad_path = alarms[i].bad_path).count() - 1
      alarms_detail.append((alarms[i],
                  time.strftime("%y-%m-%d %T", time.gmtime(alarms[i].time)),
                  alarms_info[alarms[i].alarm_id][0] - alarms_info[alarms[i].alarm_id][4], # first alarm
                  alarms_info[alarms[i].alarm_id][1],       # alarm last
                  ("%.2lf" % alarms_info[alarms[i].alarm_id][2]), # average fingerprint. (probability)
                  as0, as1, as2, num_prefix, prefix_cc,
                ))
      if len(alarms_detail) >= topx: break
    if len(alarm_ids) and len(alarms_detail) < topx:
      goon_flag = True
      alarms = []
  return alarms_detail

def alarms(request, asn=''):
  visitorStat(request)
  # recent alarms
  alarms_detail = []
  curTstr = time.strftime("%Y-%m-%d %T", time.gmtime())
  if request.method == 'POST':
    form = AlarmFilterForm(request.POST)
    if form.is_valid():
      alarms_detail = getRecentAlarms(
                float(form.cleaned_data['fig_low']),
                float(form.cleaned_data['fig_high']),
                int(form.cleaned_data['fig_last']),
                int(form.cleaned_data['topx']),
                form.cleaned_data['prefix'],
                form.cleaned_data['AS'],
                form.cleaned_data['rpki'])
  else:
    form = AlarmFilterForm(
        initial = {'topx': 10, 'fig_low': 0.6, 'fig_high': 1.0, 'fig_last': 10,
              'prefix': '', 'AS': asn} )
    alarms_detail = getDefaultRecentAlarms(10, '', asn, '')
  params = {}
  params.update(csrf(request))
  return render_to_response('alarms.html',
        dict(params.items() +
          ({'alarms': alarms_detail, 'currtime': curTstr, 'form': form}).items()))

def myAlarm(request, asn=''):
  visitorStat(request)
  # recent alarms
  alarms_detail = []
  curTstr = time.strftime("%Y-%m-%d %T", time.gmtime())
  if request.method == 'POST':
    form = AlarmFilterForm(request.POST)
    if form.is_valid():
      alarms_detail = getRecentAlarms(
                float(form.cleaned_data['fig_low']),
                float(form.cleaned_data['fig_high']),
                int(form.cleaned_data['fig_last']),
                int(form.cleaned_data['topx']),
                form.cleaned_data['prefix'],
                form.cleaned_data['AS'],
                form.cleaned_data['rpki'])
  else:
    form = AlarmFilterForm(
        initial = {'topx': 10, 'fig_low': 0.6, 'fig_high': 1.0, 'fig_last': 10,
              'prefix': '', 'AS': asn} )
    alarms_detail = getDefaultRecentAlarms(10, '', asn, '')
  params = {}
  params.update(csrf(request))
  return render_to_response('myAlarm.html',
        dict(params.items() +
          ({'alarms': alarms_detail, 'currtime': curTstr, 'form': form}).items()))

def changes(request):
  visitorStat(request)
  # recent alarms
  alarms_detail = []
  curTstr = time.strftime("%Y-%m-%d %T", time.gmtime())
  if request.method == 'POST':
    form = AlarmFilterForm(request.POST)
    if form.is_valid():
      alarms_detail = getRecentAlarms(
                float(form.cleaned_data['fig_low']),
                float(form.cleaned_data['fig_high']),
                int(form.cleaned_data['fig_last']),
                int(form.cleaned_data['topx']),
                form.cleaned_data['prefix'],
                form.cleaned_data['AS'],
                form.cleaned_data['rpki'])
  else:
    form = AlarmFilterForm(
        initial = {'topx': 10, 'fig_low': -1.0, 'fig_high': -0.6,
          'fig_last': 60,
              'prefix': '', 'AS': ''} )
    alarms_detail = getRecentAlarms(-1.0, -0.6, 60, 10, '', '', '')
  params = {}
  params.update(csrf(request))
  return render_to_response('changes.html',
        dict(params.items() +
          ({'alarms': alarms_detail, 'currtime': curTstr, 'form': form}).items()))

def getRecentAnomalies(topx, prefix, AS, rpki):
  cursor = connection.cursor()
  prefix_condition = ""
  AS_condition = ""
  rpki_condition = ""
  sql_param = []
  if prefix:
    (ipbeg, ipend, psize) = getPrefixRange(prefix)
    prefix_condition = " is_ipv6 = %s AND ipbeg >= %s AND ipend <= %s AND "
    sql_param.append(len(ipbeg) == 16)
    sql_param.append(ipbeg)
    sql_param.append(ipend)
  if AS:
    iAS = int(AS)
    AS_condition = """ (homeas = %s OR oldhomeas = %s
        OR bad_path LIKE %s OR bad_path LIKE %s
        OR bad_path LIKE %s) AND """
    sql_param.append(iAS)
    sql_param.append(iAS)
    sql_param.append('%% %s' % AS)
    sql_param.append('%s %%' % AS)
    sql_param.append('%% %s %%' % AS)
  if rpki:
    rpki_condition = " rpki = '%s' AND " % rpki
  sql_param.extend([topx])
  cursor.execute(""" SELECT alarm_id FROM alarm WHERE """
    + prefix_condition + AS_condition + rpki_condition +
    """ EXISTS (
      SELECT * FROM signature WHERE 
      signature.alarm_id = alarm.alarm_id
      AND signature.cnt00 + signature.cnt01 != 0
    ) ORDER BY alarm_id DESC LIMIT %s
    """, sql_param)
  anomalies = cursor.fetchall()
  anomalies_info = {}
  alarm_ids = []
  for am in anomalies:
    # MaxFing, MinFing, E(Fingerprints), OldOrigins, FirstProbe
    anomalies_info[am[0]] = [-1.0, 1.0, 0, 0, -1]
    alarm_ids.append(am[0])
  signatures = Signature.objects.filter(alarm_id__in = alarm_ids)
  sum = 0.0
  cnt = 0
  for i in xrange(len(signatures)):
    if (i > 0) and (signatures[i].alarm_id != signatures[i - 1].alarm_id):
      if cnt == 0:
        anomalies_info[signatures[i - 1].alarm_id][2] = 0.0
      else:
        anomalies_info[signatures[i - 1].alarm_id][2] = sum / cnt
      sum = 0.0
      cnt = 0
    if anomalies_info[signatures[i].alarm_id][0] < signatures[i].sig:
      anomalies_info[signatures[i].alarm_id][0] = signatures[i].sig
    if anomalies_info[signatures[i].alarm_id][1] > signatures[i].sig:
      anomalies_info[signatures[i].alarm_id][1] = signatures[i].sig
    if (i < len(signatures) - 1) and (
        signatures[i].alarm_id == signatures[i + 1].alarm_id):
      cnt += signatures[i + 1].elapse_time - signatures[i].elapse_time
      sum += (signatures[i + 1].elapse_time - signatures[i].elapse_time
          ) * signatures[i].sig
    else:
      cnt += 120 - signatures[i].elapse_time
      sum += (120 - signatures[i].elapse_time) * signatures[i].sig
    if anomalies_info[signatures[i].alarm_id][4] == -1:
      anomalies_info[signatures[i].alarm_id][4] = signatures[i].elapse_time
  if len(signatures) > 0:
    if cnt == 0:
      anomalies_info[signatures[len(signatures) - 1].alarm_id][2] = 0.0
    else:
      anomalies_info[signatures[len(signatures) - 1].alarm_id][2] = sum / cnt
  anomalies = Alarm.objects.filter(alarm_id__in = alarm_ids).order_by('-alarm_id')
  anomalies_detail = []
  for i in xrange(len(anomalies)):
    prefix_cc = geo.country_code_by_addr(
      anomalies[i].prefix_dec[:anomalies[i].prefix_dec.index('/')])
    if not prefix_cc: prefix_cc = ""
    as0 = as1 = as2 = 0
    if anomalies[i].bad_path:
      ASes = string.split(anomalies[i].bad_path, ' ')
      as2 = ASes[-1]
      as1 = ASes[-2]
      if len(ASes) == 3: as0 = int(ASes[0])
    num_prefix = Alarm.objects.filter(
        time = anomalies[i].time, homeas = anomalies[i].homeas,
        bad_path = anomalies[i].bad_path).count() - 1
    anomalies_detail.append((anomalies[i],
                time.strftime("%y-%m-%d %T", time.gmtime(anomalies[i].time)),
                Decimal("%.2lf" % anomalies_info[anomalies[i].alarm_id][0]), # Max Fing
                Decimal("%.2lf" % anomalies_info[anomalies[i].alarm_id][1]), # Min Fing
                ("%.2lf" % anomalies_info[anomalies[i].alarm_id][2]), # probability
                as0, as1, as2, num_prefix, prefix_cc,
                ))
  return anomalies_detail

def index(request, templatefile):
  # recent 1 alarms
  alarms_detail = getDefaultRecentAlarms(1)
  # fingerprints
  first6 = 0; sigs = []; cnt0 = []; base = 120;
  if alarms_detail:
    (first6, alarms_detail, sigs, cnt0x, cntx0, cntxx, base, upts
        ) = getFingerprints(alarms_detail[0][0].alarm_id)
  # recent 1 anomalies
  anomalies_detail = getRecentAnomalies(1, '', '', '')
  curTstr = time.strftime("%Y-%m-%d %T", time.gmtime())
  return render_to_response(templatefile, {
    'alarms': alarms_detail, 'anomalies': anomalies_detail, 'currtime': curTstr,
    'first6': first6, 'sigs': sigs,
    'cnt0x': cnt0x, 'cntx0': cntx0, 'cntxx': cntxx, 'base': base,
    'visitors': visitorStat(request, True)
    })

def contact(request):
  visitorStat(request)
  params = {}
  params.update(csrf(request))
  if request.method == 'POST':
    form = ContactForm(request.POST)
    if form.is_valid():
      cd = form.cleaned_data
      ip = request.META.get('REMOTE_ADDR', '')
      Comment.objects.create(
        ip = ip[0:64],
        name = cd['name'],
        email = cd['email'],
        message = cd['message'],
      )
      return render_to_response('contact.html',
        dict(params.items() + ({'form': form, 'greeting': 'Thanks!'}).items()))
  else:
    form = ContactForm(
      initial={'name': '', 'email': '', 'message': ''}
    )
  return render_to_response('contact.html',
        dict(params.items() + ({'form': form, 'greeting': 'Leave a message :)'}).items()))

def anomalies(request):
  visitorStat(request)
  # recent anomalies
  anomalies_detail = []
  curTstr = time.strftime("%Y-%m-%d %T", time.gmtime())
  if request.method == 'POST':
    form = AnomalyFilterForm(request.POST)
    if form.is_valid():
      anomalies_detail = getRecentAnomalies(
                int(form.cleaned_data['topx']),
                form.cleaned_data['prefix'],
                form.cleaned_data['AS'],
                form.cleaned_data['rpki'])
  else:
    form = AnomalyFilterForm(initial = {'topx': 10, 'prefix': '', 'AS': ''} )
    anomalies_detail = getRecentAnomalies(10, '', '', '')
  params = {}
  params.update(csrf(request))
  return render_to_response('anomalies.html',
        dict(params.items() +
          ({'anomalies': anomalies_detail, 'currtime': curTstr, 'form': form}).items()))

def reports(request):
  visitorStat(request)

  reportcnts = Reportcnt.objects.all().order_by('week')
  total_stable = 0
  total_stable_oa = 0
  total_stable_aa = 0
  total_stable_pa = 0
  total_hijack = 0
  total_hijack_oa = 0
  total_hijack_aa = 0
  total_hijack_pa = 0
  total_anomaly = 0
  total_anomaly_oa = 0
  total_anomaly_aa = 0
  total_anomaly_pa = 0
  #ipv6
  ipv6_stable = 0
  ipv6_stable_oa = 0
  ipv6_stable_aa = 0
  ipv6_stable_pa = 0
  ipv6_hijack = 0
  ipv6_hijack_oa = 0
  ipv6_hijack_aa = 0
  ipv6_hijack_pa = 0
  ipv6_anomaly = 0
  ipv6_anomaly_oa = 0
  ipv6_anomaly_aa = 0
  ipv6_anomaly_pa = 0
  #ipv4
  ipv4_stable = 0
  ipv4_stable_oa = 0
  ipv4_stable_aa = 0
  ipv4_stable_pa = 0
  ipv4_hijack = 0
  ipv4_hijack_oa = 0
  ipv4_hijack_aa = 0
  ipv4_hijack_pa = 0
  ipv4_anomaly = 0
  ipv4_anomaly_oa = 0
  ipv4_anomaly_aa = 0
  ipv4_anomaly_pa = 0
  for rc in reportcnts:
    rc.week = rc.week * 604800000 + 259200000
    total_stable += rc.all_stable
    total_stable_oa += rc.all_stable_oa
    total_stable_aa += rc.all_stable_aa
    total_stable_pa += rc.all_stable_pa
    total_hijack += rc.all_hijack
    total_hijack_oa += rc.all_hijack_oa
    total_hijack_aa += rc.all_hijack_aa
    total_hijack_pa += rc.all_hijack_pa
    total_anomaly += rc.all_anomaly
    total_anomaly_oa += rc.all_anomaly_oa
    total_anomaly_aa += rc.all_anomaly_aa
    total_anomaly_pa += rc.all_anomaly_pa
    #ipv6 total
    ipv6_stable += rc.ipv6_stable
    ipv6_stable_oa += rc.ipv6_stable_oa
    ipv6_stable_aa += rc.ipv6_stable_aa
    ipv6_stable_pa += rc.ipv6_stable_pa
    ipv6_hijack += rc.ipv6_hijack
    ipv6_hijack_oa += rc.ipv6_hijack_oa
    ipv6_hijack_aa += rc.ipv6_hijack_aa
    ipv6_hijack_pa += rc.ipv6_hijack_pa
    ipv6_anomaly += rc.ipv6_anomaly
    ipv6_anomaly_oa += rc.ipv6_anomaly_oa
    ipv6_anomaly_aa += rc.ipv6_anomaly_aa
    ipv6_anomaly_pa += rc.ipv6_anomaly_pa
    #ipv4 total
    ipv4_stable += rc.ipv4_stable
    ipv4_stable_oa += rc.ipv4_stable_oa
    ipv4_stable_aa += rc.ipv4_stable_aa
    ipv4_stable_pa += rc.ipv4_stable_pa
    ipv4_hijack += rc.ipv4_hijack
    ipv4_hijack_oa += rc.ipv4_hijack_oa
    ipv4_hijack_aa += rc.ipv4_hijack_aa
    ipv4_hijack_pa += rc.ipv4_hijack_pa
    ipv4_anomaly += rc.ipv4_anomaly
    ipv4_anomaly_oa += rc.ipv4_anomaly_oa
    ipv4_anomaly_aa += rc.ipv4_anomaly_aa
    ipv4_anomaly_pa += rc.ipv4_anomaly_pa

  return render_to_response('reports.html', {
      'total_stable': total_stable,
      'total_stable_oa': total_stable_oa,
      'total_stable_aa': total_stable_aa,
      'total_stable_pa': total_stable_pa,
      'total_hijack': total_hijack,
      'total_hijack_oa': total_hijack_oa,
      'total_hijack_aa': total_hijack_aa,
      'total_hijack_pa': total_hijack_pa,
      'total_anomaly': total_anomaly,
      'total_anomaly_oa': total_anomaly_oa,
      'total_anomaly_aa': total_anomaly_aa,
      'total_anomaly_pa': total_anomaly_pa,
      #ipv6
      'ipv6_stable': ipv6_stable,
      'ipv6_stable_oa': ipv6_stable_oa,
      'ipv6_stable_aa': ipv6_stable_aa,
      'ipv6_stable_pa': ipv6_stable_pa,
      'ipv6_hijack': ipv6_hijack,
      'ipv6_hijack_oa': ipv6_hijack_oa,
      'ipv6_hijack_aa': ipv6_hijack_aa,
      'ipv6_hijack_pa': ipv6_hijack_pa,
      'ipv6_anomaly': ipv6_anomaly,
      'ipv6_anomaly_oa': ipv6_anomaly_oa,
      'ipv6_anomaly_aa': ipv6_anomaly_aa,
      'ipv6_anomaly_pa': ipv6_anomaly_pa,
      #ipv4
      'ipv4_stable': ipv4_stable,
      'ipv4_stable_oa': ipv4_stable_oa,
      'ipv4_stable_aa': ipv4_stable_aa,
      'ipv4_stable_pa': ipv4_stable_pa,
      'ipv4_hijack': ipv4_hijack,
      'ipv4_hijack_oa': ipv4_hijack_oa,
      'ipv4_hijack_aa': ipv4_hijack_aa,
      'ipv4_hijack_pa': ipv4_hijack_pa,
      'ipv4_anomaly': ipv4_anomaly,
      'ipv4_anomaly_oa': ipv4_anomaly_oa,
      'ipv4_anomaly_aa': ipv4_anomaly_aa,
      'ipv4_anomaly_pa': ipv4_anomaly_pa,
      'reportcnts': reportcnts,
    })

def about(request):
  visitorStat(request)
  return render_to_response('about.html', {})

def api(request):
  visitorStat(request)
  return render_to_response('api.html', {})

def news(request):
  visitorStat(request)
  return render_to_response('news.html', {})

def getVisitors(request):
  import math
  result = {}
  nvis = visitorStat(request, True)
  citys = City.objects.all()
  merge_city = {}
  for c in citys:
    if c.pageview <= 0:
      continue
    if c.name not in merge_city:
      merge_city[c.name] = [
              c.latitude * c.pageview, c.longitude * c.pageview, c.pageview]
    else:
      counter = merge_city[c.name]
      counter[0] += c.latitude * c.pageview
      counter[1] += c.longitude * c.pageview
      counter[2] += c.pageview
    c.pageview = 0
  ncity = 0
  for k, v in merge_city.iteritems():
    citys[ncity].latitude = v[0] / v[2] / 10000
    citys[ncity].longitude = v[1] / v[2] / 10000
    citys[ncity].name = '%s: %d' % (k, v[2])
    citys[ncity].pageview = int(math.log10(v[2])) + 1
    if citys[ncity].pageview > 4:
      citys[ncity].pageview = 4
    ncity += 1
  dpvs = Visitor.objects.exclude(
        agent__icontains='bot').exclude(
        agent__icontains='spider').exclude(
        agent__icontains='python').extra(
          {'day': 'UNIX_TIMESTAMP(time) DIV 86400'}
        ).values('day').annotate(dpv=Count('visitor_id')).order_by('day')
  result['citys']=citys
  result['visitors']=nvis
  result['dpvs']=dpvs
  return result

def vmap(request):
  import math
  nvis = visitorStat(request, True)
  citys = City.objects.all()
  merge_city = {}
  for c in citys:
    if c.pageview <= 0:
      continue
    if c.name not in merge_city:
      merge_city[c.name] = [
              c.latitude * c.pageview, c.longitude * c.pageview, c.pageview]
    else:
      counter = merge_city[c.name]
      counter[0] += c.latitude * c.pageview
      counter[1] += c.longitude * c.pageview
      counter[2] += c.pageview
    c.pageview = 0
  ncity = 0
  for k, v in merge_city.iteritems():
    citys[ncity].latitude = v[0] / v[2] / 10000
    citys[ncity].longitude = v[1] / v[2] / 10000
    citys[ncity].name = '%s: %d' % (k, v[2])
    citys[ncity].pageview = int(math.log10(v[2])) + 1
    if citys[ncity].pageview > 4:
      citys[ncity].pageview = 4
    ncity += 1
  dpvs = Visitor.objects.exclude(
        agent__icontains='bot').exclude(
        agent__icontains='spider').exclude(
        agent__icontains='python').extra(
          {'day': 'UNIX_TIMESTAMP(time) DIV 86400'}
        ).values('day').annotate(dpv=Count('visitor_id')).order_by('day')
  return render_to_response('vmap.html', {
      'citys': citys, 'visitors': nvis, 'dpvs': dpvs
    })

def visitmap(request):
  import math
  nvis = visitorStat(request, True)
  citys = City.objects.all()
  merge_city = {}
  for c in citys:
    if c.pageview <= 0:
      continue
    if c.name not in merge_city:
      merge_city[c.name] = [
              c.latitude * c.pageview, c.longitude * c.pageview, c.pageview]
    else:
      counter = merge_city[c.name]
      counter[0] += c.latitude * c.pageview
      counter[1] += c.longitude * c.pageview
      counter[2] += c.pageview
    c.pageview = 0
  ncity = 0
  for k, v in merge_city.iteritems():
    citys[ncity].latitude = v[0] / v[2] / 10000
    citys[ncity].longitude = v[1] / v[2] / 10000
    citys[ncity].name = '%s: %d' % (k, v[2])
    citys[ncity].pageview = int(math.log10(v[2])) + 1
    if citys[ncity].pageview > 4:
      citys[ncity].pageview = 4
    ncity += 1
  dpvs = Visitor.objects.exclude(
        agent__icontains='bot').exclude(
        agent__icontains='spider').exclude(
        agent__icontains='python').extra(
          {'day': 'UNIX_TIMESTAMP(time) DIV 86400'}
        ).values('day').annotate(dpv=Count('visitor_id')).order_by('day')
  return render_to_response('vmap-small.html', {
      'citys': citys, 'visitors': nvis, 'dpvs': dpvs
    })

def page_not_found(request):
    return contact(request)
    #visitorStat(request)
    #return render_to_response('404.html', {})

def maintain(request):
    return render_to_response('maintain.html', {})

